package cn.edu.zjut.medlinebackend.controller;


import cn.edu.zjut.medlinebackend.mapper.FavoriteMapper;
import cn.edu.zjut.medlinebackend.mapper.GroupfileMapper;
import cn.edu.zjut.medlinebackend.mapper.MembersMapper;
import cn.edu.zjut.medlinebackend.mapper.UserMapper;
import cn.edu.zjut.medlinebackend.model.Favorite;
import cn.edu.zjut.medlinebackend.model.User;
import cn.edu.zjut.medlinebackend.service.FavoriteService;
import cn.edu.zjut.medlinebackend.service.FileService;
import cn.edu.zjut.medlinebackend.service.GroupfileService;
import cn.edu.zjut.medlinebackend.service.PostService;
import cn.edu.zjut.medlinebackend.utils.MyUtils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import com.example.demo.common.Result;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import static cn.edu.zjut.medlinebackend.constant.FileConstant.FILE_ROOT_PATH;

@RestController
@RequestMapping("/file")
public class FileController {

    @Resource
    private FileService fileService;

    @Resource
    private PostService postService;


    @Resource
    private FavoriteService favoriteService;

    @Resource
    private GroupfileService groupfileService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private MembersMapper membersMapper;

    @Resource
    private GroupfileMapper groupfileMapper;

    @Value("${ip:localhost}")
    String ip;

    @Value("${server.port}")
    String port;


    //文件上传方法
    @PostMapping("/upload")
    public Result upload(@RequestParam("files") MultipartFile[] files, String[] tags, HttpServletRequest request) throws IOException {
        List<String> downloadUrls = new ArrayList<>();
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];
            String tag = "";
            if(tags != null){
                tag = tags[i];  // Get the corresponding tag for the current file
            }

            String originalFilename = file.getOriginalFilename();// 文件的原始名称
            String mainName = FileUtil.mainName(originalFilename);// aaa
            String extName = FileUtil.extName(originalFilename);// png
            if (!FileUtil.exist(FILE_ROOT_PATH)) {
                FileUtil.mkdir(FILE_ROOT_PATH);// 如果当前文件的父级目录不存在，就创建
            }
            String newFileName = generateFileName(mainName, extName);  // 生成新的文件名
            File saveFile = new File(FILE_ROOT_PATH + File.separator + newFileName);
            file.transferTo(saveFile);// 存储文件到本地的磁盘里面去
            //todo 用户校验，防止用户不存在，查不到id
            // 保存文件到数据库
            if (fileService.uploadFileToDB(newFileName, tag, request)) {  // Save the tag along with the file
                System.out.println("上传成功！");
            } else {
                System.out.println("上传失败！");
            }
            String downloadUrl = "http://" + ip + ":" + port + "/file/download/" + newFileName;
            downloadUrls.add(downloadUrl);//文件下载地址
        }

        return Result.success(downloadUrls);//返回文件的链接，这个链接就是文件的下载地址，这个下载地址就是我的后台提供出来的
    }


    // 辅助方法：生成新的文件名，避免重名
    private String generateFileName(String mainName, String extName) {
        String fileName = mainName + "." + extName;
        if (FileUtil.exist(FILE_ROOT_PATH + File.separator + fileName)) {
            fileName = System.currentTimeMillis() + "_" + mainName + "." + extName;
        }
        return fileName;
    }


    //文件下载方法
    @GetMapping("/download")
    public void download(String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));  // 附件下载
        String filePath = FILE_ROOT_PATH + File.separator + fileName;
        if (!FileUtil.exist(filePath)) {
            return;
        }

        if(postService.addDownloadNum(fileName)){
            System.out.println("下载量增加成功");
        }else {
            System.out.println("下载量增加失败");
        }
        byte[] bytes = FileUtil.readBytes(filePath);
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(bytes);  // 数组是一个字节数组，也就是文件的字节流数组
        outputStream.flush();
        outputStream.close();
    }


    //文件预览方法
    @GetMapping("/preview")
    public void preview(String fileName, HttpServletResponse response) throws IOException {
        response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(fileName, "UTF-8"));  // 预览
        String filePath = FILE_ROOT_PATH + File.separator + fileName;
        if (!FileUtil.exist(filePath)) {
            return;
        }
        byte[] bytes = FileUtil.readBytes(filePath);
        ServletOutputStream outputStream = response.getOutputStream();
        PDDocument document = PDDocument.load(bytes); //加载pdf
        PDDocumentInformation info = document.getDocumentInformation(); //获得文档属性对象
        info.setTitle(fileName); //修改标题属性  这个标题会被展示
        document.setDocumentInformation(info);
        document.save(outputStream); //修改完直接输出到响应体中
        document.close();
        outputStream.write(bytes);  // 数组是一个字节数组，也就是文件的字节流数组
        outputStream.flush();
        outputStream.close();
    }

    @GetMapping("/delete")
    public boolean deleteFile(String fileName) {
        return fileService.deleteFileByName(fileName);
    }


    /**.
     *  文件收藏
     * @param fileName
     * @param request
     */
    @GetMapping("/doFavorite")
    public String favorite(String fileName, HttpServletRequest request){
        String username = MyUtils.getCookieValue(request, "username");
        User userByUsername = userMapper.getUserByUsername(username);
        if(userByUsername==null) return "请先登录";
        Integer userId= userByUsername.getId();
        //todo 用户校验，防止多次收藏
        if(favoriteService.seleteFavoriteFile(fileName, userId)){
            return "收藏失败";
        }

        // 保存文件到数据库
        if(favoriteService.favoriteFile(fileName, userId)){
            return "收藏成功";
        }else {
            return "收藏失败";
        }
    }

    /**
     *  取消收藏
     * @param fileName
     * @param request
     */
    @GetMapping("/deleteFavorite")
    public String deleteFavorite(String fileName, HttpServletRequest request){
        String username = MyUtils.getCookieValue(request, "username");
        User userByUsername = userMapper.getUserByUsername(username);
        if(userByUsername==null) return "请先登录";
        Integer userId= userByUsername.getId();
        if(!favoriteService.seleteFavoriteFile(fileName, userId)){
            return "取消收藏失败";
        }

        //todo 用户校验，防止用户不存在，查不到id
        // 保存文件到数据库
        if(favoriteService.deleteFavoriteFile(fileName, userId)){
            return "取消收藏成功";
        }else {
            return "取消收藏失败";
        }
    }

    /**
     *  文件共享
     * @param fileNames
     * @param request
     */
    @PostMapping("/doShareFile")
    public String shareFile(@RequestParam("selectedFiles") List<String> fileNames, @RequestParam("groupId") Integer groupId,HttpServletRequest request){
        String username = MyUtils.getCookieValue(request, "username");
        User userByUsername = userMapper.getUserByUsername(username);
        if(userByUsername==null) return "请先登录";
        Integer userId= userByUsername.getId();
        //todo 用户校验，防止多次共享
        for(String fileName:fileNames){
            if(groupfileService.seleteGroupFile(fileName, userId,groupId)){
                return fileName+"已共享，请勿重复共享！";
            }
            // 保存文件到数据库
            if(!groupfileService.uploadGroupFile(fileName, userId,groupId)){
                return "共享失败";
            }
        }
        return "共享成功";
    }

    /**
     *  取消共享
     * @param fileName
     * @param request
     */
    @GetMapping("/deleteShareFile")
    public String deleteShareFile(String fileName, @RequestParam("groupId") Integer groupId ,HttpServletRequest request){
        String username = MyUtils.getCookieValue(request, "username");
        User userByUsername = userMapper.getUserByUsername(username);
        if(userByUsername==null) return "请先登录";
        Integer userId= userByUsername.getId();
        if(!groupfileService.seleteGroupFile(fileName, userId,groupId)){
            return "取消共享失败";
        }

        //todo 用户校验，防止用户不存在，查不到id
        // 保存文件到数据库
        if(groupfileService.deleteGroupFile(fileName, userId,groupId)){
            return "取消共享成功";
        }else {
            return "取消共享失败";
        }
    }

    //预览图片
    @GetMapping(value="/previewimg",produces = MediaType.IMAGE_PNG_VALUE)
    public byte[] getImage(String imgName) throws Exception {
        BufferedImage bufferedImage = ImageIO.read(new FileInputStream("./img/"+imgName));
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "png", out);
        return out.toByteArray();
    }

}
